﻿using Amazon.S3.Model;
using BulkUploadGovernanceFiles.Models;
using BulkUploadGovernanceFiles.MongoSpecification;
using Sustainalytics.AwsS3.Client;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;

using System.Linq;
using System.Threading;

namespace BulkUploadGovernanceFiles
{
    public class MongoFileProcessor
    {
        private readonly CorporateDataRepository _corporateDataRepository;
        private readonly MongoGridFSRepository _mongoGridFsRepository;
        private readonly GovernancePdfProfileMetadataRepository _governancePdfProfileMetadataRepository;
        private readonly SimpleLogging _log;
        private readonly Action<string, Action<FileStream>> _getFileStreamByFullPath;
        private readonly string _bucketName;

        public MongoFileProcessor()
        {
            _governancePdfProfileMetadataRepository = new GovernancePdfProfileMetadataRepository();
            _corporateDataRepository = new CorporateDataRepository();

            _mongoGridFsRepository = new MongoGridFSRepository();
            _log = new SimpleLogging();
            _bucketName = ConfigurationManager.AppSettings["s3-governance-reports"];
        }

        public MongoFileProcessor(Action<string, Action<FileStream>> getFileStreamByFullPath)
            : this()
        {
            _getFileStreamByFullPath = getFileStreamByFullPath;
        }

        public void ProcessFile(FileInfo file, GovernancePdfType type)
        {
            //Thread.Sleep(10000);
            int fileCapitalIqId;
            int.TryParse(file.Name.Replace("IQ", "").Replace(".pdf", "").Trim(), out fileCapitalIqId);
            //var haveCapitalIqId = new HaveCapitalIqIdSpecification(fileCapitalIqId);

            var corporateData = _corporateDataRepository.GetByCompanyId(fileCapitalIqId);

            if (corporateData != null)
            {
                //RemoveFile(corporateData.Id, file.Name);
                var fileId = GetFileId(corporateData.Id, type);
                var pdfMetadata = CreateGovernancePdfProfileMetadata(fileId, corporateData.CompanyName, corporateData.Id, type);
                _governancePdfProfileMetadataRepository.Insert(pdfMetadata, type);
                byte[] fileContentByteArray = File.ReadAllBytes(file.FullName);
                SaveFileInS3(corporateData.Id  + ".pdf", type.ToString(), fileContentByteArray);
            }
            else
            {
                _log.Log("NOT FOUND in corporate data :" + file.Name);
            }
        }

        private Guid GetFileId(Guid companyId, GovernancePdfType type)
        {
            Guid fileId = Guid.NewGuid();
            var exisingFile = _governancePdfProfileMetadataRepository.GetByCompanyIdAndGovernancePdfType(companyId, type).FirstOrDefault();
            if (exisingFile != null && exisingFile.FileId != Guid.Empty)
            {
                fileId = exisingFile.FileId;
                _governancePdfProfileMetadataRepository.RemoveByComapnyId(companyId, type);
            }

            return fileId;
        }

        private string CreateMongoFileName(string  companyName, GovernancePdfType type)
        {
            var fileName = companyName.Replace(" ", "") + "_" + type.ToString() + ".pdf";
            return fileName;
        }

        private GovernancePdfProfileMetadata CreateGovernancePdfProfileMetadata(Guid fileId, string copmpanyName,  Guid companyId, GovernancePdfType type)
        {
            var pdfMetadata = new GovernancePdfProfileMetadata
            {
                Id = Guid.NewGuid(),
                FileId = fileId,
                CompanyId = companyId,
                OperationType = UpdateOperationType.Created,
                GovernancePdfType = type,
                LastOperationUserName = ConfigManagement.UserName,
                LastOperationDateTime = DateTime.UtcNow,
                FileName = CreateMongoFileName(copmpanyName, type),
            };
            return pdfMetadata;
        }

        private void SavePdfFile(Guid fileId, string mongoFileName, string fullFileName)
        {
            const string contentType = "application/pdf";
            var mongoData = _mongoGridFsRepository.NewFile(mongoFileName, fileId, contentType);

            using (mongoData.Item1)
            {
                _getFileStreamByFullPath(fullFileName, fs => fs.CopyTo(mongoData.Item1));
            }
        }

        public void RemoveAll(GovernancePdfType type)
        {
            _governancePdfProfileMetadataRepository.RemoveAll(type);
            ClearS3Bucket(type);
        }

        public bool ClearS3Bucket(GovernancePdfType type)
        {
            bool isError = false;
            S3ClientSettings _s3ClientSettings;

            _s3ClientSettings = new S3ClientSettings
            {
                AccessKey = ConfigurationManager.AppSettings["accesKeyId"],
                SecretAccessKey = ConfigurationManager.AppSettings["awsSecretKey"],
                ServiceEndPoint = ConfigurationManager.AppSettings["s3ServiceEndPoint"],
            };

            using (var s3Client = new S3Client(_s3ClientSettings))
            {
                try
                {
                    var myBucket = _bucketName.Split('/')[0];
                    var myPrefix = _bucketName.Split('/')[1] + "/" + type.ToString() + "/";
                    s3Client.DeleteBulk(myBucket, myPrefix);
                }
                catch (Exception ex) { isError = true; }
            }
            return !isError;
        }

        public bool SaveFileInS3(string fileName, string governancePdfType, byte[] fileContentByteArray)
        {
            bool isError = false;
            S3ClientSettings _s3ClientSettings;
            
            _s3ClientSettings = new S3ClientSettings
            {
                AccessKey = ConfigurationManager.AppSettings["accesKeyId"],
                SecretAccessKey = ConfigurationManager.AppSettings["awsSecretKey"],
                ServiceEndPoint = ConfigurationManager.AppSettings["s3ServiceEndPoint"],
            };

            using (var s3Client = new S3Client(_s3ClientSettings))
            {
                try
                {
                    var fullPath = string.Format("{0}/{1}", governancePdfType, fileName);
                    s3Client.UploadFile(_bucketName, fullPath, fileContentByteArray);
                }
                catch (Exception) { isError = true; }
            }
            return !isError;
        }
    }
}
